using System;
using Combat;
using PrimeTween;
using UnityEngine;
using Utils;

namespace Level
{
    public class StageManager : MonoBehaviour
    {
        public int Stage { get; private set; }

        public Timer RestTimer { get; private set; }

        [SerializeField] private DifficultySetting difficultySetting;
        [SerializeField] private EnemySpawner enemySpawner;
        [SerializeField] private WeaponSwitch weaponSwitch;
        
        [SerializeField] private float restTime = 5f;
        
        private Timer _spawnTimer;
        private int _currentStageEnemyCount;
        private int _spawnedEnemyCount;
        private int _killedEnemyCount;
        

        private void Start()
        {
            RestTimer = new Timer(restTime, UpdateStage);
            _spawnTimer = new Timer(difficultySetting.GetEnemySpawnIntervalAtRound(Stage), SpawnEnemy);

            _currentStageEnemyCount = difficultySetting.EnemyCountBase;
            
            RestTimer.Reset();
            
            ExplodeOnDied.AnyThingExploded += ExplodeOnDied_AnyThingExploded;
        }

        private void OnDestroy()
        {
            ExplodeOnDied.AnyThingExploded -= ExplodeOnDied_AnyThingExploded;
        }

        private void Update()
        {
            RestTimer.Tick();
            _spawnTimer.Tick();
        }
        
        private void ExplodeOnDied_AnyThingExploded()
        {
            // Assume enemy
            _killedEnemyCount++;

            if (_killedEnemyCount >= _currentStageEnemyCount)
            {
                Stage++;

                _currentStageEnemyCount += difficultySetting.EnemyCountAdditionPerRound;
                Transform newEnemyType = difficultySetting.GetNewEnemyTypeAtRound(Stage);
                if (newEnemyType != null)
                {
                    enemySpawner.AddSpecialEnemyType(newEnemyType);
                }

                int unlockWeaponIndex = difficultySetting.GetNewWeaponTypeAtRound(Stage);
                if (unlockWeaponIndex != 0)
                {
                    Tween.Delay(1f, () => weaponSwitch.UnlockWeapon(unlockWeaponIndex));
                }
                
                _killedEnemyCount = 0;
                _spawnedEnemyCount = 0;
                RestTimer.Reset();
            }
        }

        private void UpdateStage()
        {
            _spawnTimer.Reset(difficultySetting.GetEnemySpawnIntervalAtRound(Stage));
        }

        private void SpawnEnemy()
        {
            int remainingEnemyCount = _currentStageEnemyCount - _spawnedEnemyCount;
            int countPerBurst = difficultySetting.GetEnemyCountPerBurstAtRound(Stage);
            int spawnCount = Mathf.Min(remainingEnemyCount, countPerBurst);
            enemySpawner.SpawnRandom(spawnCount);
            _spawnedEnemyCount += spawnCount;

            if (_spawnedEnemyCount < _currentStageEnemyCount)
            {
                _spawnTimer.Reset(difficultySetting.GetEnemySpawnIntervalAtRound(Stage));
            }
        }
    }
}